
QuestGuruSettings = {}
local QGC_FACTION = UnitFactionGroup("player");
-- Sound set definitions
local soundSets = {
-- Classic QuestGuru Sounds.
	default = {
	questComplete = "Sound/Interface/levelup2.ogg",
	objectiveComplete = "Sound/Interface/AuctionWindowClose.ogg",
	objectiveProgress = "Sound/Interface/AuctionWindowOpen.ogg",
	},
--	Alliance Sound Set.
	peasant = {
	questComplete = "Sound/Creature/Peasant/PeasantReady1.ogg",
	objectiveComplete = "Sound/Creature/Peasant/PeasantYes1.ogg",
	objectiveProgress = "Sound/Creature/Peasant/PeasantYes4.ogg",
	},
--	Horde Sound Set.
	peon = { -- this set acts as default for new installations
	questComplete = "Sound/Creature/Peon/PeonBuildingComplete1.ogg",
	objectiveComplete = "Sound/Creature/Peon/PeonReady1.ogg",
	objectiveProgress = "Sound/Creature/Peon/PeonYes3.ogg",
	},
--Plays no sounds.
	quiet = {
	questComplete = "",
	objectiveComplete = "",
	objectiveProgress = "",
	},
}

-- The saved variables
QGSSndVars = {} -- will be initialized in PLAYER_LOGIN

-- The sounds to play
local sounds = nil -- will be initialized in PLAYER_LOGIN

-- The QGSssage level codes
local messageLevels = {
  -- increQGSnt in multiples of 10 so we can add levels later without breaking stuff
  none = 0,
  completion = 10,
  objectives = 20,
  all = 30
}

local QGS = CreateFrame("Frame")
local events = {}

QGS.questIndex = 0
QGS.questId = 0
QGS.completeCount = 0


QGS.msgLvl = messageLevels.all

local function countCompleteObjectives(index)
  local n = 0
  for i = 1, GetNumQuestLeaderBoards(index) do
    local _, _, finished = GetQuestLogLeaderBoard(i, index)
    if finished then
      n = n + 1
    end
  end
  return n
end

function QGS:setQuest(index)
  self.questIndex = index
  if index>0 then
    local _, _, _, _, _, _, _, id = GetQuestLogTitle(index)
    self.questId = id
    if id and id>0 then
      self.completeCount = countCompleteObjectives(index)
    end
  end
end

function QGS:checkQuest()
  if self.questIndex>0 then
    local index = self.questIndex
    self.questIndex = 0
    -- Beware! One of the output arguQGSnts was removed in WoD
    local title, level, _, _, _, complete, daily, id = GetQuestLogTitle(index)
    local link = GetQuestLink(index)
    if id==self.questId then
      if id and id>0 then
        local objectivesComplete = countCompleteObjectives(index)
        if complete then
          if QGS.msgLvl >= messageLevels.completion then
            print("["..level.."] '"..link.."': complete");
          end
          self:Play(sounds and sounds.questComplete)
        elseif objectivesComplete>self.completeCount then
          if QGS.msgLvl >= messageLevels.objectives then
            print("["..level.."] '"..link.."': objective complete ("..objectivesComplete.."/"..GetNumQuestLeaderBoards(index)..")");
          end
          self:Play(sounds and sounds.objectiveComplete)
        else
          if QGS.msgLvl >= messageLevels.all then
             print("["..level.."] '"..link.."': updated");
          end
          self:Play(sounds and sounds.objectiveProgress)
        end
      end
    end
  end
end

function QGS:init()
  self:SetScript("OnEvent", function(frame, event, ...)
    local handler = events[event]
    if handler then
      -- dispatch events that were auto-registered by naming convention
      handler(frame, ...)
    end
  end)
  for k,v in pairs(events) do
    self:RegisterEvent(k)
  end
end

function QGS:Play(sound)
  if sound and sound~="" then
--    print("QGS debug message: Playing:", sound)
    PlaySoundFile(sound);
  end
end

function QGS:SetSoundSet(setName, silent)
  if setName and soundSets[setName] then
    QGSSndVars.ActiveSet = setName
    sounds = soundSets[setName]
    if not(silent) then
      print("Switching to sound set |cFF44FF00"..setName.."|r")
      QGS:Play(sounds.questComplete)
    end
  else
    print("Recognized sound set names are:")
    for k,v in pairs(soundSets) do
      if k==QGSSndVars.ActiveSet then
        print("  "..k.."      (*)")
      else
        print("  "..k)
      end
    end
  end
end

function QGS:SetMessageLevel(messageLevel)
  local levelCode = messageLevels[messageLevel]
  if levelCode==nil then
    -- ignore silently now
  else
    QGSSndVars.Messages = messageLevel
    QGS.msgLvl = levelCode
  end
end


function QGS:SetMessageLevelCmd(messageLevel)
  if messageLevel==nil or messageLevel=="" then
    print("The current message verbosity level is '"..QGSSndVars.Messages.."'")
  else
    local levelCode = messageLevels[messageLevel]
    if levelCode==nil then
      print("Unrecognized message verbosity level '"..messageLevel.."'. Expecting one of :")
      for k,v in pairs(messageLevels) do
        print("  "..k);
      end
    else
      QGS:SetMessageLevel(messageLevel)
      print("Setting message verbosity to "..QGSSndVars.Messages)
    end
  end
end


-- ................................................................
-- event handlers

function events:UNIT_QUEST_LOG_CHANGED(unit)
  if unit=="player" then
    QGS:checkQuest()
  end
end

function events:QUEST_WATCH_UPDATE(index)
  -- This event triggers just *before* the changes are registered
  -- in the quest log, giving a great opportunity to quantify changes
  -- in the subsequent UNIT_QUEST_LOG_CHANGED
  QGS:setQuest(index)
end

function events:PLAYER_LOGIN()
  -- Saved variables are stable now
  if not(QGSSndVars.ActiveSet) then
--  	if UnitFactionGroup("player")=="HORDE" then
--    	QGSSndVars.ActiveSet = "peasant"
--    else
--    	QGSSndVars.ActiveSet = "peon"
--    end
    	QGSSndVars.ActiveSet = "default"
  end
  if not(QGSSndVars.Messages) then
    QGSSndVars.Messages = "objectives"
    -- one of "objectives", "completion", "none"
  end
  QGS:SetMessageLevel(QGSSndVars.Messages)
  QGS:SetSoundSet(QGSSndVars.ActiveSet, true)
end

-- ................................................................
-- command interface
--
SLASH_QGSOUND1 = "/QGS"
SLASH_QGSOUND2 = "/qgs"

function SlashCmdList.QGSOUND(msg, editbox)
 local cmd, rest = msg:match("^(%S*)%s*(.-)$")
 QGS:Command(cmd, rest)
end

function QGS:Command(command, arg)
 local handler = self["CMD"..command]
 if handler then
   handler(self, arg)
 else
   if command~="" then
     print("Unknown QGS command '"..command.."'");
   end
   print("  /qgs set <soundsetname>")
   print("     Sets the sound set and plays its quest completion sound")
   print("  /qgs set")
   print("     Lists the known sound set names")
   print("  /qgs test <quest or objective or part>")
   print("     Plays the current 'quest', 'objective' or 'part' completion sound")
   print("  /qgs message <objectives or completion or none>")
   print("     Sets verbosity of message in the chat log to 'objectives', 'completion' or 'none'")
   print("  The current sound set is |cFF44FF00"..QGSSndVars.ActiveSet.."|r");
   print("  The current message verbosity is |cFF44FF00"..QGSSndVars.Messages.."|r");
 end
end


function QGS:CMDtest(arg)
	if arg=="1" or arg=="quest" then
		print("Playing |cFFCCCC44quest complete|r sound of sound set |cFF44FF00"..QGSSndVars.ActiveSet.."|r")
		self:Play(sounds and sounds.questComplete)
	elseif arg=="2" or arg=="objective" then
		print("Playing |cFFCCCC44objective complete|r sound of sound set |cFF44FF00"..QGSSndVars.ActiveSet.."|r")
		self:Play(sounds and sounds.objectiveComplete)
	elseif arg=="3" or arg=="part" then
		print("Playing |cFFCCCC44objective progress|r sound of sound set |cFF44FF00"..QGSSndVars.ActiveSet.."|r")
		self:Play(sounds and sounds.objectiveProgress)
	elseif arg=="4" or arg=="faction" then
		print("|cFFCCCC44Player is|r from the |cFF44FF00"..QGC_FACTION.."|r")
	else
		print("  Usage: /qgs test <sound id>")
		print("    Recognized values for <sound id> are:")
		print("      '1' or 'quest' for the quest complete sound")
		print("      '2' or 'objective' for the objective complete sound")
		print("      '3' or 'part' for the objective part update sound")
	end
end

function QGS:CMDset(arg)
 self:SetSoundSet(arg)
end

function QGS:CMDmessage(arg)
 self:SetMessageLevelCmd(arg)
end

function QGS:CMDmsg(arg)
 self:SetMessageLevelCmd(arg)
end


-- ................................................................
-- must be last line:
QGS:init()
